/**   
* TODO 
* @author zhanghui   
* @date 2016年4月14日 上午11:46:05  
*/
package com.nebula.upms.admin.service.impl;

import com.nebula.common.framework.BaseService;
import com.nebula.common.util.UUIDGenerator;
import com.nebula.upms.admin.service.IndexService;
import com.nebula.upms.service.model.po.*;
import com.nebula.upms.service.model.vo.UpmsAppSystemVO;
import com.nebula.upms.service.model.vo.UpmsPrivilegeVO;
import com.nebula.upms.service.model.vo.UpmsUserVO;
import com.nebula.upms.service.support.constant.UpmsFinal;
import com.nebula.upms.service.support.constant.UpmsLocalFinal;
import com.nebula.upms.service.support.datasource.UpmsDs;
import eu.bitwalker.useragentutils.Browser;
import eu.bitwalker.useragentutils.OperatingSystem;
import eu.bitwalker.useragentutils.UserAgent;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/** 
* TODO
* @author zhanghui
* @date 2016年4月14日 上午11:46:05  
*/
@Service("indexService")
@Transactional
public class IndexServiceImpl extends BaseService implements IndexService {
	private static String TOKEN_ALIVE_FILD="TOKEN_ALIVE_FILD";
	/**
	* Description:
	* @param loginName
	* @param loginPassword
	* @return
	**/
	@Override
	public UpmsUserVO loginIn(String loginName, String loginPassword) {
		UpmsPersonPOExample example=new UpmsPersonPOExample();
		example.createCriteria().andLoginNameEqualTo(loginName).andLoginPasswordEqualTo(loginPassword);
		UpmsPersonPO upmsPersonPO= UpmsDs.instance().mybatis().ds().mapper().selectFirstByExample(example);
		
		if(null!=upmsPersonPO){
			Map<String,Object> params=new HashMap<>();
			params.put("personId", upmsPersonPO.getPersonId());
			UpmsUserVO upmsUserVO=UpmsDs.instance().mybatis().ds().mapper("PrivilegeMapper").selectOne("selectUserVO", params);
			
			params.clear();
			params.put("staffId", upmsUserVO.getStaffId());
			List<UpmsAppSystemVO> appSystemVOList=UpmsDs.instance().mybatis().ds().mapper("PrivilegeMapper").selectList("selectUserAppSystemList", params);
			List<UpmsPrivilegeVO> privilegeVOList=UpmsDs.instance().mybatis().ds().mapper("PrivilegeMapper").selectList("selectUserPrivilegeList", params);
			this.bulidUserPrivilege(upmsUserVO, appSystemVOList, privilegeVOList);
			return upmsUserVO;
			
		}
		return null;
	}
	
	/**
	* Description:
	* @param staffId
	* @return
	**/
	@Override
	public UpmsUserVO getUpmsUserVOByStaffId(String staffId) {
		UpmsStaffPOExample example=new UpmsStaffPOExample();
		example.createCriteria().andStaffIdEqualTo(staffId);
		UpmsStaffPO upmsStaffPO=UpmsDs.instance().mybatis().ds().mapper().selectFirstByExample(example);
		
		Map<String,Object> params=new HashMap<>();
		params.put("personId", upmsStaffPO.getPersonId());
		UpmsUserVO upmsUserVO=UpmsDs.instance().mybatis().ds().mapper("PrivilegeMapper").selectOne("selectUserVO", params);
		params.clear();
		params.put("staffId", upmsUserVO.getStaffId());
		List<UpmsAppSystemVO> appSystemVOList=UpmsDs.instance().mybatis().ds().mapper("PrivilegeMapper").selectList("selectUserAppSystemList", params);
		List<UpmsPrivilegeVO> privilegeVOList=UpmsDs.instance().mybatis().ds().mapper("PrivilegeMapper").selectList("selectUserPrivilegeList", params);
		this.bulidUserPrivilege(upmsUserVO, appSystemVOList, privilegeVOList);
		return upmsUserVO;
	}
	
	private void bulidUserPrivilege(UpmsUserVO upmsUserVO,List<UpmsAppSystemVO> appSystemVOList,List<UpmsPrivilegeVO> privilegeVOList){
		
		List<UpmsAppSystemVO> appSystemList=new ArrayList<>();
		for (UpmsAppSystemVO upmsAppSystemVO : appSystemVOList) {
			
			UpmsPrivilegeVO upmsPrivilegeVORoot=null;
			for (UpmsPrivilegeVO upmsPrivilegeVO : privilegeVOList) {
				if(upmsPrivilegeVO.getType().equals(UpmsLocalFinal.PRIVILEGE_TYPE_Y0A)&&
						upmsAppSystemVO.getAppSystemId().equals(upmsPrivilegeVO.getAppSystemId())){
					upmsPrivilegeVORoot=upmsPrivilegeVO;
					break;
				}
			}
			
			List<UpmsPrivilegeVO> privilegeVOFolderList=new ArrayList<>();
			for (UpmsPrivilegeVO upmsPrivilegeVO : privilegeVOList) {
				if(upmsPrivilegeVORoot.getPrivilegeId().equals(upmsPrivilegeVO.getPrivilegePid())){
					privilegeVOFolderList.add(upmsPrivilegeVO);
				}
			}
			
			List<UpmsPrivilegeVO> folderList=new ArrayList<>();
			for (UpmsPrivilegeVO privilegeVOFolder : privilegeVOFolderList) {
				
				List<UpmsPrivilegeVO> upmsPrivilegeVOMenuList=new ArrayList<>();
				for (UpmsPrivilegeVO upmsPrivilegeVO : privilegeVOList) {
					if(privilegeVOFolder.getPrivilegeId().equals(upmsPrivilegeVO.getPrivilegePid())){
						upmsPrivilegeVOMenuList.add(upmsPrivilegeVO);
					}
				}
				privilegeVOFolder.setUpmsPrivilegeVOMenuList(upmsPrivilegeVOMenuList);
				folderList.add(privilegeVOFolder);
			}
			upmsAppSystemVO.setUpmsPrivilegeVOFolderList(folderList);
			appSystemList.add(upmsAppSystemVO);
		}
		upmsUserVO.setUpmsAppSystemVOList(appSystemList);
	}

	/**
	* Description:
	* @param upmsUserVO
	* @param userAgent
	**/
	@Override
	public void saveUserSession(UpmsUserVO upmsUserVO, UserAgent userAgent,String token,String ip) {
		Browser browser = userAgent.getBrowser();
		OperatingSystem os = userAgent.getOperatingSystem();
		
		UpmsStaffSessionPO upmsStaffSessionPO=new UpmsStaffSessionPO();
		upmsStaffSessionPO.setSessionId(UUIDGenerator.random32UUID());
		upmsStaffSessionPO.setStaffId(upmsUserVO.getStaffId());
		upmsStaffSessionPO.setPersonName(upmsUserVO.getPersonName());
		upmsStaffSessionPO.setLoginName(upmsUserVO.getLoginName());
		upmsStaffSessionPO.setToken(token);
		upmsStaffSessionPO.setLoginTime(new Date().getTime());
		upmsStaffSessionPO.setLoginIp(ip);
		upmsStaffSessionPO.setLoginOs(os.getName());
		upmsStaffSessionPO.setLoginBrowser(browser.getName());
		upmsStaffSessionPO.setBrowserVersion(userAgent.getBrowserVersion().getVersion());
		upmsStaffSessionPO.setPersonId(upmsUserVO.getPersonId());
		upmsStaffSessionPO.setCompanyId(upmsUserVO.getCompanyId());
		upmsStaffSessionPO.setCompanyName(upmsUserVO.getCompanyName());
		upmsStaffSessionPO.setDepartmentId(upmsUserVO.getDepartmentId());
		upmsStaffSessionPO.setDepartmentName(upmsUserVO.getDepartmentName());
		UpmsDs.instance().mybatis().ds().mapper().insert(upmsStaffSessionPO);
		
		UpmsStaffSessionLogPO log=this.sessionToLog(upmsStaffSessionPO);
		UpmsDs.instance().mybatis().ds().mapper().insert(log);
		upmsUserVO.setUpmsAppSystemVOList(null);
		//RedisHelper.set(UpmsFinal.KEYHEAD_UPMS_SESSION+token,UpmsFinal.FIELD_UPMS_USERVO ,upmsUserVO, UpmsFinal.SESSION_TIME_OUT);
		//RedisHelper.set(UpmsFinal.KEYHEAD_UPMS_ALIVE+token,UpmsFinal.FIELD_UPMS_TOKEN,token, UpmsFinal.ALIVE_TIME_OUT);
		UpmsDs.instance().redis().set(UpmsFinal.KEYHEAD_UPMS_SESSION,token,upmsUserVO,UpmsFinal.SESSION_TIME_OUT);
		UpmsDs.instance().redis().set(UpmsFinal.KEYHEAD_UPMS_ALIVE,token,token,UpmsFinal.ALIVE_TIME_OUT);
	}
	
	private UpmsStaffSessionLogPO sessionToLog(UpmsStaffSessionPO upmsStaffSessionPO){
		UpmsStaffSessionLogPO log=new UpmsStaffSessionLogPO();
		log.setSessionLogId(upmsStaffSessionPO.getSessionId());
		log.setStaffId(upmsStaffSessionPO.getStaffId());
		log.setPersonName(upmsStaffSessionPO.getPersonName());
		log.setLoginName(upmsStaffSessionPO.getLoginName());
		log.setToken(upmsStaffSessionPO.getToken());
		log.setLoginTime(upmsStaffSessionPO.getLoginTime());
		log.setLoginIp(upmsStaffSessionPO.getLoginIp());
		log.setLoginOs(upmsStaffSessionPO.getLoginOs());
		log.setLoginBrowser(upmsStaffSessionPO.getLoginBrowser());
		log.setBrowserVersion(upmsStaffSessionPO.getBrowserVersion());
		log.setPersonId(upmsStaffSessionPO.getPersonId());
		log.setCompanyId(upmsStaffSessionPO.getCompanyId());
		log.setCompanyName(upmsStaffSessionPO.getCompanyName());
		log.setDepartmentId(upmsStaffSessionPO.getDepartmentId());
		log.setDepartmentName(upmsStaffSessionPO.getDepartmentName());
		
		return log;
	}
	

	/**
	* Description:
	* @param token
	**/
	@Override
	public void deleteUserSession(String token) {
		UpmsStaffSessionPOExample example1=new UpmsStaffSessionPOExample();
		example1.createCriteria().andTokenEqualTo(token);
		UpmsDs.instance().mybatis().ds().mapper().deleteByExample(example1);
		
		UpmsStaffSessionLogPOExample example2=new UpmsStaffSessionLogPOExample();
		example2.createCriteria().andTokenEqualTo(token);
		UpmsStaffSessionLogPO log=UpmsDs.instance().mybatis().ds().mapper().selectFirstByExample(example2);
		if(null!=log){
			log.setLoginOutTime(new Date().getTime());
			UpmsDs.instance().mybatis().ds().mapper().updateByPrimaryKeySelective(log);
		}else{
			UpmsStaffSessionPO sess=UpmsDs.instance().mybatis().ds().mapper().selectFirstByExample(example1);
			if(null!=sess){
				log=this.sessionToLog(sess);
				log.setLoginOutTime(new Date().getTime());
				UpmsDs.instance().mybatis().ds().mapper().insertSelective(log);
			}
		}
		
		//RedisHelper.delete(UpmsFinal.KEYHEAD_UPMS_SESSION+token,UpmsFinal.FIELD_UPMS_USERVO);
		//RedisHelper.delete(UpmsFinal.KEYHEAD_UPMS_ALIVE+token,UpmsFinal.FIELD_UPMS_TOKEN);

		UpmsDs.instance().redis().remove(UpmsFinal.KEYHEAD_UPMS_SESSION,token);
		UpmsDs.instance().redis().remove(UpmsFinal.KEYHEAD_UPMS_ALIVE,token);
	}

	/**
	* Description:
	* @param token
	* @return
	**/
	@Override
	public boolean isTokenAlive(String token) {
		
		if(null==UpmsDs.instance().redis().get(UpmsFinal.KEYHEAD_UPMS_ALIVE,token,String.class)){//超时
			return false;
		}else{
			UpmsDs.instance().redis().set(UpmsFinal.KEYHEAD_UPMS_ALIVE,token,token,UpmsFinal.ALIVE_TIME_OUT);
			return true;
		}
	}

	/**
	* Description:
	**/
	@Override
	public void userAlive() {
		UpmsStaffSessionPOExample example=new UpmsStaffSessionPOExample();
		List<UpmsStaffSessionPO> sessionList=UpmsDs.instance().mybatis().ds().mapper().selectByExample(example);
		for (UpmsStaffSessionPO upmsStaffSessionPO : sessionList) {
			String token=upmsStaffSessionPO.getToken();
			//System.out.println(RedisHelper.get(UpmsFinal.KEYHEAD_UPMS_ALIVE+token, UpmsFinal.FIELD_UPMS_TOKEN));
			if(null==UpmsDs.instance().redis().get(UpmsFinal.KEYHEAD_UPMS_ALIVE,token,String.class)){//用户不存在心跳
				this.deleteUserSession(token);
			}
		}
		
		
	}
}
